//
// Created by jerry on 2024/8/22.
//

#ifndef DATASTRUCTURE_SHARED_PTR_H
#define DATASTRUCTURE_SHARED_PTR_H
#include <iostream>
namespace mycode{
    template <class T>
            struct Del{
        void operator()(T* Ptr){ delete Ptr; };
    };
    template <class T,class D = Del<T>>
    class shared_ptr{
    public:
        typedef shared_ptr<T,D>& Self;
        typedef shared_ptr<T,D>* Ptr;
        shared_ptr():_ptr(nullptr),_pcount(new int(1)){};
        shared_ptr(T* ptr):_ptr(ptr),_pcount(new int(1)){};
        shared_ptr(const shared_ptr<T,D>& ref):_ptr(ref._ptr),_pcount(ref._pcount){(*_pcount)++;};
        Self operator=(const shared_ptr<T,D>& ref){
            release();//首先将自己本来调用的空间delete
            _ptr = ref._ptr;
            _pcount = ref._pcount;
            return *this;
        }
        void release() noexcept{
            if((*_pcount) == 1) {
                _del(_ptr);
                delete _pcount;
                _ptr = _pcount = nullptr;
            }
            else --(*_pcount);
        }
        ~shared_ptr() {
            release();
        }
        const T* operator->() const { return _ptr; }
        const T& operator*() const { return *_ptr; }
        T* operator->() { return _ptr; }
        T& operator*() { return *_ptr; }
        int count() const { return *_pcount; }
    private:
        T* _ptr;
        D _del;
        int* _pcount;
    };
}
template <class T>
struct Del{
    void operator()(const T* Ptr) {
        delete Ptr;
        std::cout << "destractor const Ptr" << std::endl;
    }


};
void testMyShared_ptr()
{
    mycode::shared_ptr<int> ptri(new int());

}

#endif //DATASTRUCTURE_SHARED_PTR_H
